#include "WMCallback.h"

///Copyright (c) 2009-2010 T. Klepzig 

map<HWND, WMCallback*> WMCallback::instances;
WMCallback* WMCallback::tmpInstance = 0;


WMCallback::WMCallback(HINSTANCE hInstance, LPVOID tag)
{
	this->tag = tag;

	wndProc = 0;
	tagWndProc = 0;

	LPCWSTR className=TEXT("CassiopeiaMessageCallbackWnd");

	WNDCLASSEX wndClass={0};
	wndClass.cbSize=sizeof(wndClass);
	wndClass.lpfnWndProc=WndProc;
	wndClass.hInstance=hInstance;
	wndClass.lpszClassName=className;
	RegisterClassEx(&wndClass);

	tmpInstance = this;
	hWnd=CreateWindowEx(0,className,0,0,20,20,200,200,0,0,hInstance,0);
}

WMCallback::~WMCallback()
{
	instances.erase(hWnd);
	DestroyWindow(hWnd);
}

HWND WMCallback::GetHWnd()
{
	return hWnd;
}

void WMCallback::OnTaggedWmCallback(TAGWNDPROC proc)
{
	tagWndProc = proc;
}

void WMCallback::OnWmCallback(WNDPROC proc)
{
	wndProc = proc;
}


LRESULT CALLBACK WMCallback::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (instances.find(hWnd) == instances.end() && tmpInstance)
	{
		instances[hWnd] = tmpInstance;
		tmpInstance = 0;
	}

	if (instances.find(hWnd) != instances.end())
	{
		if (instances[hWnd]->tagWndProc)
			return instances[hWnd]->tagWndProc(hWnd, uMsg, wParam, lParam, instances[hWnd]->tag);
		else if (instances[hWnd]->wndProc)
			return instances[hWnd]->wndProc(hWnd, uMsg, wParam, lParam);
		else
			return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
}

